package test.reflact;

import org.junit.Test;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.*;

public class UserApi {

    /**
     * 查询用户基本信息，模拟耗时150ms
     */
    public String queryUserInfo(long userId) {
        String userInfo = "userInfo: " + userId;

        try {
            TimeUnit.MILLISECONDS.sleep(150L);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return userInfo;
    }

    /**
     * 查询用户地址，模拟耗时200ms
     */
    public String queryUserAddress(long userId) {
        String userAddress = "userAddress: " + userId;

        try {
            TimeUnit.MILLISECONDS.sleep(200L);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return userAddress;
    }

    @Test
    public void testUseFutureTask() throws ExecutionException, InterruptedException {
        UserApi userApi = new UserApi();
        long startTime = System.currentTimeMillis();

        Callable<String> userInfoCallable = new Callable<String>() {
            @Override
            public String call() throws Exception {
                return userApi.queryUserInfo(1);
            }
        };
        Callable<String> userAddressCallable = new Callable<String>() {
            @Override
            public String call() throws Exception {
                return userApi.queryUserAddress(2);
            }
        };
        FutureTask<String> userInfoFutureTask = new FutureTask<>(userInfoCallable);
        FutureTask<String> userAddressFutureTask = new FutureTask<>(userAddressCallable);

        new Thread(userInfoFutureTask).start();
        new Thread(userAddressFutureTask).start();

        String userInfo = userInfoFutureTask.get();
        String userAddress = userAddressFutureTask.get();
        System.out.println(userInfo + userAddress);
        System.err.println("testUseFutureTask 耗时：" + (System.currentTimeMillis() - startTime));
    }

    public static void main(String[] args) throws Exception {

// 开始时间

        long start = System.currentTimeMillis();

// 模拟数据

        List<String> list = new ArrayList<String>();

        for (int i = 1; i <= 100000; i++) {

            list.add(i + "");

        }

// 每500条数据开启一条线程

        int threadSize = 10000;

// 总数据条数

        int dataSize = list.size();

// 线程数

        int threadNum = dataSize / threadSize + 1;

// 定义标记,过滤threadNum为整数

        boolean special = dataSize % threadSize == 0;

// 创建一个线程池

        ExecutorService exec = Executors.newFixedThreadPool(threadNum);

// 定义一个任务集合

        List<Callable<Integer>> tasks = new ArrayList<Callable<Integer>>();

        Callable<Integer> task = null;

        List<String> cutList = null;

// 确定每条线程的数据

        for (int i = 0; i < threadNum; i++) {

            if (i == threadNum - 1) {

                if (special) {

                    break;

                }

                cutList = list.subList(threadSize * i, dataSize);

            } else {

                cutList = list.subList(threadSize * i, threadSize * (i + 1));

            }

// System.out.println("第" + (i + 1) + "组：" + cutList.toString());

            final List<String> listStr = cutList;

            task = new Callable<Integer>() {

                @Override
                public Integer call() throws Exception {

                    System.out.println(Thread.currentThread().getName() + "线程：" + listStr);

                    return 1;

                }

            };

// 这里提交的任务容器列表和返回的Future列表存在顺序对应的关系

            tasks.add(task);

        }

        List<Future<Integer>> results = exec.invokeAll(tasks);

        for (Future<Integer> future : results) {

            System.out.println(future.get());

        }

// 关闭线程池

        exec.shutdown();

        System.out.println("线程任务执行结束");

        System.err.println("执行任务消耗了 ：" + (System.currentTimeMillis() - start) + "毫秒");

    }

@Test
    public void test() throws ParseException {
    long start = System.currentTimeMillis();
    System.out.println(start);
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
    String time = "2022-03-03T09:04:19.184Z";
//    time = time.replace("Z", " UTC");
    Date parse = sdf.parse(time);
    long time1 = parse.getTime();
    System.out.println(time1);
}

}